package pl.iachoo.ctl.tabory.dao.hibernate.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Restrictions;

import pl.iachoo.ctl.tabory.dao.api.services.ICompositionService;
import pl.iachoo.ctl.tabory.dao.data.vo.CompositionVO;
import pl.iachoo.ctl.tabory.dao.data.vo.VagonVO;
import pl.iachoo.ctl.tabory.dao.hibernate.services.BaseDaoService;

public class CompositionDaoServiceImpl extends BaseDaoService<CompositionVO>
		implements ICompositionService {

	private final Logger logger = Logger
			.getLogger(CompositionDaoServiceImpl.class);

	public CompositionDaoServiceImpl(SessionFactory sessionFactory) {
		super(sessionFactory);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<CompositionVO> getListAllCompositions() throws Exception {
		logger.debug("Getting all Compositions.");
		Transaction transaction = null;
		Session session = null;
		List<CompositionVO> listCompositions = new ArrayList<CompositionVO>();
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			listCompositions = session.createCriteria(CompositionVO.class)
					.list();
			transaction.commit();
			logger.debug(listCompositions);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
		return listCompositions;
	}

	@Override
	public CompositionVO getComposition(String internalId) throws Exception {
		logger.debug("Getting Composition for internalId: " + internalId);
		Transaction transaction = null;
		Session session = null;
		CompositionVO composition = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			Criteria criteria = session.createCriteria(VagonVO.class);
			criteria.add(Restrictions.eq("internalId", internalId));
			composition = (CompositionVO) criteria.uniqueResult();
			transaction.commit();
			logger.debug(composition);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
		return composition;
	}

	@Override
	public CompositionVO getComposition(Long id) throws Exception {
		logger.debug("Getting Composition for Id: " + id);
		Transaction transaction = null;
		Session session = null;
		CompositionVO composition = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			Criteria criteria = session.createCriteria(VagonVO.class);
			criteria.add(Restrictions.eq("id", id));
			composition = (CompositionVO) criteria.uniqueResult();
			transaction.commit();
			logger.debug(composition);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
		return composition;
	}

	@Override
	public CompositionVO saveUpdateComposition(CompositionVO composition)
			throws Exception {
		logger.debug("Save/Update Composition: " + composition);
		if (composition.getId() != null) {
			updateComposition(composition);
		} else {
			saveComposition(composition);
		}
		return composition;
	}

	private void saveComposition(CompositionVO composition) throws Exception {
		logger.debug("Saving composition: " + composition);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			session.save(composition);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

	private void updateComposition(CompositionVO composition) throws Exception {
		logger.debug("Updating composition: " + composition);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			session.update(composition);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

	@Override
	public void deleteComposition(CompositionVO composition) throws Exception {
		logger.debug("Deleting: " + composition);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			CompositionVO tmpComposition = (CompositionVO) session.get(
					CompositionVO.class, composition.getId());
			session.delete(tmpComposition);
			transaction.commit();
			logger.debug("Delete OK.");
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

}
